package com.gzz.controller;


import cn.hutool.core.lang.UUID;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gzz.common.DeviceInfo;
import com.gzz.common.Location;
import com.gzz.common.R;
import com.gzz.pojo.BaseInfo;
import com.gzz.pojo.OnlineUser;
import com.gzz.pojo.User;
import com.gzz.service.OnlineUserService;
import com.gzz.service.OssUploadService;
import com.gzz.service.UserService;
import com.gzz.service.impl.WebSocket;
import com.gzz.utils.IPUtil;
import com.gzz.utils.JWTUtils;
import com.gzz.vo.UserDetailVo;
import com.gzz.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.TimeUnit;

import static com.gzz.common.RedisUtils.User_Login_Key;
import static com.gzz.common.RedisUtils.User_Login_TTL;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 */
@RestController
@RequestMapping("/api/user")
public class UserController {
	@Autowired
	UserService userService;

	@Autowired
	StringRedisTemplate stringRedisTemplate;

	@Autowired
	OnlineUserService onlineUserService;
	@Autowired
	OssUploadService ossUploadService;
	@PostMapping("/upload")
	public R<String> UploadImg(HttpServletRequest request, HttpServletResponse response,
							   String type, @RequestParam("file") MultipartFile multipartFile){
		String imgUrl = ossUploadService.uploadFile(multipartFile,type);
		String token = request.getHeader("token");
		//获取用户id
		Long id = JWTUtils.parseToken(token);
		User user = userService.getById(id);
		if(user==null){
			response.setStatus(401);
			return R.error("身份失败");
		}
		if(!user.getStatus()){
			response.setStatus(401);
			return R.error("账号已封禁");
		}
		if(imgUrl!="error"){
			user.setUserAvatar(imgUrl);
			userService.updateById(user);
			return R.success(imgUrl);
		}
		return R.error(imgUrl);
	}

	@GetMapping("/isLogin")
	public R<String> isLogin(HttpServletRequest request){
		String token = request.getHeader("token");
		Long id = JWTUtils.parseToken(token);
		User user = userService.getById(id);
		if(user==null){
			return R.error("未登录");
		}
		return R.success("已经登录");

	}


	@PostMapping("/login")
	public R<UserVo> login(HttpServletRequest httpServletRequest, @RequestBody User user){
		String password = user.getPassword();
		Digester md5 = new Digester(DigestAlgorithm.MD5);

		password = md5.digestHex(password);

		LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();

		lambdaQueryWrapper.eq(User::getUsername,user.getUsername());

		User usr = userService.getOne(lambdaQueryWrapper);

		if(usr == null){
			return R.error("用户名不存在!");
		}
		else{
			if(!usr.getStatus()){

				return R.error("账号已封禁");
			}
			String pw = usr.getPassword();
			if(!pw.equals(password)){
				return R.error("密码错误!");
			}
			else{
				//登录成功
				//1.保存用户信息到redis

				String token = JWTUtils.getToken(usr.getUserId());
				//以token为key存入redis
				String tokenKey = User_Login_Key+usr.getUserId().toString();
			    UserVo userVo = new UserVo();
				BeanUtils.copyProperties(usr,userVo);
				stringRedisTemplate.opsForValue().set(tokenKey, token);
				stringRedisTemplate.expire(tokenKey,User_Login_TTL, TimeUnit.MINUTES);

				// 2.获取用户登录设备信息，还有ip地址
				String ipAdd = IPUtil.getIpAddr(httpServletRequest);
				DeviceInfo deviceInfo = IPUtil.getDevice(httpServletRequest);
				String loc = IPUtil.getCityInfo(ipAdd);
				OnlineUser onlineUser = new OnlineUser();
				onlineUser.setUserId(usr.getUserId());
				onlineUser.setStatus(true);
				onlineUser.setBrowserType(deviceInfo.getBrowserType());
				onlineUser.setLoginTime(new Date());
				onlineUser.setLocation(loc);
				onlineUser.setIpAddress(ipAdd);
				onlineUser.setOsType(deviceInfo.getOsType());
				onlineUser.setClientType(deviceInfo.getClientType());
				onlineUserService.saveOrUpdate(onlineUser);
				//3.将token返回到前端
				return R.success(userVo).add("token",token);
			}
		}
	}


    // 一键求助
	@GetMapping("/seekhelp")
	public R<String> seekhelp(HttpServletRequest httpServletRequest, double longitude,double latitude){
		CopyOnWriteArraySet<WebSocket> webSockets = WebSocket.getWebSocketSet();
		Location location = new Location(longitude,latitude);
		try {
			// 向管理端监听的websocket的客户端发送游客的位置坐标
			WebSocket.sendMessage(JSON.toJSONString(location),"2");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return R.success("成功");
	}


	@PostMapping("/register")
	public R<Long> getRegister(@RequestBody User user)
	{
		QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
		userQueryWrapper.eq("username",user.getUsername());
		if(userService.count(userQueryWrapper)!=0)
		{
			return R.error("用户名已被使用请重新输入！！");
		}
		Long userId = (long)(1e9+Math.random()*9e9);
		user.setUserId(userId);
		Digester md5 = new Digester(DigestAlgorithm.MD5);

		String password = user.getPassword();

		user.setPassword(md5.digestHex(password));

		userService.save(user);
		User user1 = userService.getOne(userQueryWrapper);
		return R.success(user1.getUserId());
	}
	@PostMapping("/validate")
	public R getValidate(@RequestBody User user)
	{
		String str = user.getPhone();
		if (str == null){
			return R.error("请输入手机号");
		}

		for (char c : str.toCharArray ()) {
			if (!Character.isDigit(c)){
				return R.error("请输入数字");
			}

		}
		UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
		userUpdateWrapper.eq("user_Id",user.getUserId());
		userUpdateWrapper.set("phone",user.getPhone());
		userService.update(userUpdateWrapper);
		return R.success(true);

	}
//	@PostMapping ("/reset")
//	public R changeUser(HttpServletRequest request,  @RequestBody User user)
//	{
//		String token = request.getHeader("token");
//		Long id = JWTUtils.parseToken(token);
//		userService.removeById(id);
//		userService.save(user);
//		return R.success(true);
//	}
	/**
	 * 管理端获取用户列表
	 */
	@GetMapping("/adminlist")
	public R<PageInfo<UserDetailVo>> getBaseInfoListbyAdmin(int pageNum, int pageSize, String userName, Long userId, Integer status,String userArea,Integer sex){
		// 设置分页
		PageHelper.startPage(pageNum,pageSize);
		// 根据查询条件获取用户信息
		List<UserDetailVo> r =userService.getUserDetailVoList(userName,userId,status,userArea,sex);
		// 将得到的数据传入分页对象中，并返回给前端
		PageInfo<UserDetailVo> pageInfo = new PageInfo<>(r);

		return R.success(pageInfo);
	}
	/**
	 * 改变用户的是否可访问的状态
	 */
	@GetMapping("/updateStatus")
	public R<String> updateStatus(Long userId,boolean status){
		// mybatisplus修改执行器,通过编程的方式修改数据库数据，而不是直接写sql语句
		LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
		lambdaUpdateWrapper.eq(User::getUserId,userId).set(User::getStatus,status);
		// 如果修改成功，返回true
		boolean update = userService.update(lambdaUpdateWrapper);
		if(update){
			return R.success("修改成功");
		}else{
			return R.error("修改失败");
		}

	}
	/**
	 * 修改用户信息
	 */
	@GetMapping ("/reset")
	public R changeUser(HttpServletRequest request,  @RequestParam(name = "username")String username,@RequestParam(name = "sex")String sex,@RequestParam(name="userarea")String userarea,@RequestParam(name="phone")String phone,@RequestParam(name="password")String ppassword)
	{
		// 通过请求头中的token解析出用户id
		String token = request.getHeader("token");
		Long id = JWTUtils.parseToken(token);
		// mybatisplus修改执行器,通过编程的方式修改数据库数据，而不是直接写sql语句
		UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
		userUpdateWrapper.eq("user_id",id);
		userUpdateWrapper.set("sex",Integer.valueOf(sex));
		userUpdateWrapper.set("username",username);
		userUpdateWrapper.set("phone",phone);
		userUpdateWrapper.set("user_area",userarea);
		userService.update(userUpdateWrapper);
		return R.success(true);
	}
	/**
	 * 获取用户信息
	 */
	@GetMapping("/find")
	public R<User> getUser(HttpServletRequest request)
	{
		// 通过请求头中的token解析出用户id
		String token = request.getHeader("token");
		Long id = JWTUtils.parseToken(token);
		// 调用mybatisplus的方法getById,通过id获取用户信息
		User user = userService.getById(id);
		return R.success(user);

	}

}

